package com.geekgo.flowcontroller;

import com.geekgo.flowcontroller.core.acquire.IRLimitAcquirable;
import com.geekgo.flowcontroller.utils.CglibProxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Method;
import java.util.Collection;

/**
 * @author HeHaoyang
 * @version 2016/8/3 16:40
 */
public class FlowControllerInterceptor implements MethodInterceptor {

    public static final Logger LOGGER = LogManager.getLogger(FlowControllerInterceptor.class);
    private FlowControllerContext context;

    public FlowControllerInterceptor(FlowControllerContext context) {
        this.context = context;
    }

    private void methodExecuteAcquire(Method method,Object[] parameters){
        String methodKey = method.toGenericString();
        Collection<IRLimitAcquirable> acquirableCollections = context.getAcquirableByKey(methodKey);
        if(acquirableCollections!=null&&acquirableCollections.size()>0){
            for(IRLimitAcquirable acquirable:acquirableCollections){
                acquirable.acquire(parameters);
            }
        }
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        this.methodExecuteAcquire(method,objects);
        LOGGER.debug("run method:{}",method);
        return methodProxy.invokeSuper(o,objects);
    }

    public <T> T create(Class<T> target){
        return target.cast(CglibProxy.createProxy(target,this));
    }
}
